package com.kitty.game.rank.service;

import com.kitty.common.utils.SpringUtils;
import com.kitty.common.core.SchedulerManager;
import com.kitty.game.ServerService;
import com.kitty.game.activity.service.other.YingXiongHuiHandler;
import com.kitty.game.activity.service.other.ZhengDaoDianHandler;
import com.kitty.game.chat.message.RespEquipInfo;
import com.kitty.game.enter.FiedValue;
import com.kitty.game.equip.model.EquipField;
import com.kitty.game.rank.RankDataPool;
import com.kitty.game.rank.message.RespCrossRankView;
import com.kitty.game.rank.message.RespRankClientInfo;
import com.kitty.game.rank.message.RespRankPetInfo;
import com.kitty.game.rank.message.RespTopUser;
import com.kitty.game.rank.model.param.RankReqParam;
import com.kitty.game.rank.model.pojo.RankViewData;
import com.kitty.game.rank.model.record.RankRecord;
import com.kitty.game.rank.service.handler.*;
import com.kitty.game.role.message.ReqGeneralNotify;
import com.kitty.game.role.model.Role;
import com.kitty.game.team.message.RespMsg;
import com.kitty.game.utils.TimeUtil;
import com.kitty.mina.message.Message;
import com.kitty.mina.message.MessagePusher;
import lombok.extern.slf4j.Slf4j;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.http.Request;
import org.nutz.http.Response;
import org.nutz.http.Sender;
import org.nutz.json.Json;
import org.nutz.json.JsonFormat;
import org.nutz.lang.Strings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
//后加
import com.kitty.game.rank.service.handler.BullyRankHandler;
import com.kitty.game.rank.service.handler.ChildLevelRankHandler;
import com.kitty.game.rank.service.handler.DefenseRankHandler;
import com.kitty.game.rank.service.handler.EquipRankHandler;
import com.kitty.game.rank.service.handler.FeiXianDuXieRankHandler;
import com.kitty.game.rank.service.handler.FuMoRankHandler;
import com.kitty.game.rank.service.handler.MagPowerRankHandler;
import com.kitty.game.rank.service.handler.MonthTaoRankHandler;
import com.kitty.game.rank.service.handler.PartyCapitalRankHandler;
import com.kitty.game.rank.service.handler.PetRankHandler;
import com.kitty.game.rank.service.handler.PhyPowerRankHandler;
import com.kitty.game.rank.service.handler.RoleLevelRankHandler;
import com.kitty.game.rank.service.handler.SpeedRankHandler;
import com.kitty.game.rank.service.handler.TaoRankHandler;
import com.kitty.game.rank.service.handler.TowerMirrorRankHandler;
import com.kitty.game.rank.service.handler.TowerRankHandler;
import com.kitty.game.rank.service.handler.XiangYaoRankHandler;
import com.kitty.game.rank.service.handler.YingXiongRankHandler;
import com.kitty.game.rank.service.handler.ZhengDaoRankHandler;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**排行榜业务处理类*/
@Service
@Slf4j
public class RankService {


    public void init() {
        /**加载排行榜数据*/
        loadRank();

        /**启动定时保存排行榜数据*/
        long initialDelay = 1 * TimeUtil.ONE_MINUTE;
        /**每隔5分钟保存一次*/
        long period = 5 * TimeUtil.ONE_MINUTE;
        SchedulerManager.getInstance().scheduleAtFixedRate(this::updateRank, initialDelay, period);
        SchedulerManager.getInstance().scheduleAtFixedRate(this::saveRank, initialDelay, period);
    }


    /**保存排行榜数据*/
    public void saveRank() {
        SpringUtils.getBean(XiangYaoRankHandler.class).save();
        SpringUtils.getBean(FuMoRankHandler.class).save();
        SpringUtils.getBean(FeiXianDuXieRankHandler.class).save();
        SpringUtils.getBean(FuMo2RankHandler.class).save();
        SpringUtils.getBean(FeiXianDuXie2RankHandler.class).save();
        SpringUtils.getBean(ZhengDaoRankHandler.class).save();
        SpringUtils.getBean(TowerRankHandler.class).save();
        SpringUtils.getBean(TowerMirrorRankHandler.class).save();
        SpringUtils.getBean(PetRankHandler.class).save();
        SpringUtils.getBean(EquipRankHandler.class).save();
        SpringUtils.getBean(YingXiongRankHandler.class).save();
        SpringUtils.getBean(BullyRankHandler.class).save();
//        SpringUtils.getBean(NewHelpRankHandler.class).save();
        SpringUtils.getBean(ChildLevelRankHandler.class).save();
    }

    /**加载排行榜数据*/
    private void loadRank() {
        SpringUtils.getBean(RoleLevelRankHandler.class).init();
        SpringUtils.getBean(TaoRankHandler.class).init();
        SpringUtils.getBean(MonthTaoRankHandler.class).init();
        SpringUtils.getBean(PhyPowerRankHandler.class).init();
        SpringUtils.getBean(MagPowerRankHandler.class).init();
        SpringUtils.getBean(DefenseRankHandler.class).init();
        SpringUtils.getBean(SpeedRankHandler.class).init();
        SpringUtils.getBean(ZhanLiRankHandler.class).init();
        SpringUtils.getBean(XiangYaoRankHandler.class).init();
        SpringUtils.getBean(FuMoRankHandler.class).init();
        SpringUtils.getBean(FeiXianDuXieRankHandler.class).init();
        SpringUtils.getBean(FuMo2RankHandler.class).init();
        SpringUtils.getBean(FeiXianDuXie2RankHandler.class).init();
        SpringUtils.getBean(ZhengDaoRankHandler.class).init();
        SpringUtils.getBean(TowerRankHandler.class).init();
        SpringUtils.getBean(TowerMirrorRankHandler.class).init();
        SpringUtils.getBean(PetRankHandler.class).init();
        SpringUtils.getBean(EquipRankHandler.class).init();
        SpringUtils.getBean(YingXiongRankHandler.class).init();
        SpringUtils.getBean(PartyCapitalRankHandler.class).init();
        SpringUtils.getBean(BullyRankHandler.class).init();
//        SpringUtils.getBean(NewHelpRankHandler.class).init();
        SpringUtils.getBean(ChildLevelRankHandler.class).init();

        loadRankView();
    }

    private void updateRank() {
        SpringUtils.getBean(ZhengDaoDianHandler.class).updateRank();
        SpringUtils.getBean(YingXiongHuiHandler.class).updateRank();
    }
    /**
     * 个人排行信息
     */
    public void rankMeInfo(Role role) {
        RespRankClientInfo respRankClientInfo = new RespRankClientInfo();
        respRankClientInfo.setList(new ArrayList<>());
        respRankClientInfo.getList().add(new FiedValue(857, 0));//帮战胜利次数
        respRankClientInfo.getList().add(new FiedValue(855, role.getPartyName()));//帮派名
        respRankClientInfo.getList().add(new FiedValue(861, 0));//伏魔最高排名
        respRankClientInfo.getList().add(new FiedValue(861, 0));//除暴最高排名
        respRankClientInfo.getList().add(new FiedValue(866, 0));//道行排名
        respRankClientInfo.getList().add(new FiedValue(859, 0));//降妖最高排名
        respRankClientInfo.getList().add(new FiedValue(858, 0));//升级时间
        respRankClientInfo.getList().add(new FiedValue(2001, 0));//飞仙渡邪最高排名
        respRankClientInfo.getList().add(new FiedValue(989, 0));//2阶伏魔最高排名
        respRankClientInfo.getList().add(new FiedValue(990, 0));//2阶伏魔最高排名
        respRankClientInfo.getList().add(new FiedValue(991, 0));//2阶飞仙最高排名
        respRankClientInfo.getList().add(new FiedValue(924, 0));//斗宠大会排行
        respRankClientInfo.getList().add(new FiedValue(862, 0));//通天塔最高排行
        respRankClientInfo.getList().add(new FiedValue(31, role.getLevel()));//等级
        respRankClientInfo.getList().add(new FiedValue(195, 0));//竞技场最高排名
        respRankClientInfo.getList().add(new FiedValue(44, role.getPolar()));//相性
        respRankClientInfo.getList().add(new FiedValue(865, 0));//所在帮派资金
        respRankClientInfo.getList().add(new FiedValue(864,0));//通天塔最高层数
        respRankClientInfo.getList().add(new FiedValue(854, 0));//帮派福利 salary
        respRankClientInfo.getList().add(new FiedValue(863, 0));//不知道什么 higest_yasby
        respRankClientInfo.getList().add(new FiedValue(856, 0));//不知道什么population
        MessagePusher.pushMessage(role, respRankClientInfo);
    }

    /**
     * 显示排行榜上的物品信息
     */
    public void info(Role role, ReqGeneralNotify reqGeneralNotify) {
        //reqGeneralNotify.getStatus() 是UUID
        String gid = reqGeneralNotify.getStatus();
        RankViewData rankViewData = getRankViewData(gid, reqGeneralNotify.getString());
        if (rankViewData != null) {
            RespEquipInfo respEquipInfo = new RespEquipInfo();
            respEquipInfo.setList(rankViewData.getFieldList());
            MessagePusher.pushMessage(role, respEquipInfo);
        } else {
            RespMsg respMsg = new RespMsg();
            respMsg.setMsg("物品信息异常。");
            MessagePusher.pushMessage(role, respMsg);
        }
    }


    /**
     * 显示排行榜的宠物信息
     */
    public void petInfo(Role role, ReqGeneralNotify reqGeneralNotify) {
        String gid = reqGeneralNotify.getStatus();
        RankViewData rankViewData = getRankViewData(gid, reqGeneralNotify.getString());
        if (rankViewData != null) {
            RespRankPetInfo respRankPetInfo = new RespRankPetInfo();
            respRankPetInfo.setList(rankViewData.getFieldList());
            MessagePusher.pushMessage(role, respRankPetInfo);
        } else {
            RespMsg respMsg = new RespMsg();
            respMsg.setMsg("宠物信息异常。");
            MessagePusher.pushMessage(role, respMsg);
        }

    }

    private RankViewData getRankViewData(String gid, String serverName) {
        /**在当前服，则直接在当前服缓存查询，否则到登录服查询*/
        if (SpringUtils.getBean(ServerService.class).getServer().getName().equals(serverName) ) {
            return RankDataPool.rankViewMap.get(gid);
        } else {
            return fetchRankView(gid);
        }
    }

    /**发送对应排行榜数据到客户端*/
    public void pushRankInfo(Role role, ReqGeneralNotify reqGeneralNotify) {
        System.out.println(System.currentTimeMillis());
        String status = reqGeneralNotify.getStatus();

        short type = 0;
        String range = null;
        if (status.contains(":")) {
            String[] split = status.split(":");
            type = Short.parseShort(split[0]);
            range = split[1];
        } else {
            type = Short.parseShort(status);
        }

        Message rankResponse = getRankResponse(role, type, range);
        MessagePusher.pushMessage(role, rankResponse);
        System.out.println(System.currentTimeMillis());
    }

    public Message getRankResponse(Role role, short type, String range) {
        Function<RankReqParam, Message> rankHandler = RankDataPool.rankHanlers.get(type);
        if (rankHandler != null) {
            return rankHandler.apply(new RankReqParam(type, range));
        }

        /**默认没有数据*/
        RespTopUser respTopUser = new RespTopUser();
        respTopUser.setSize((short) 0);
        respTopUser.setType(type);
        respTopUser.setList(new ArrayList<>());
        respTopUser.setCookie(new Long(System.currentTimeMillis() / 1000).intValue());
        return respTopUser;
    }

    /**上传排行榜数据到登录服*/
    public void uploadRankToLogin() {
        String serverName = SpringUtils.getBean(ServerService.class).getServer().getName();
        for (Map.Entry<Serializable, Function<String, List<RankRecord>>> entry : RankDataPool.kfRankHandlers.entrySet()) {
            String keyStr = (String)entry.getKey();
            String range = null;
            if (keyStr.contains(":")){
                range = keyStr.split(":")[1];
            }

            List<RankRecord> records = entry.getValue().apply(range);
            if (records == null || records.size() == 0) {continue;}

            Map<String, Object> params = new HashMap<>();
            params.put("key", entry.getKey());
            params.put("data", Json.toJson(records, JsonFormat.compact()));
            params.put("serverName", serverName);

            Request request = Request.create(SpringUtils.getBean(ServerService.class).getLoginServerUrl()+"/kf_rank/upload", Request.METHOD.POST).setParams(params);
            Sender.create(request).setTimeout(1000).send();
        }
    }

    public void fetch(Role role, short rankType, String levelLimit) {
        String key = getKey(rankType, levelLimit);
        if(rankType == 103 || rankType == 104 || rankType == 105 || rankType == 106 || rankType == 111 ){
            key = key+"-"+rankType;
        }
        Map<String, Object> params = new HashMap<>();
        params.put("key", key);

        Request request = Request.create(SpringUtils.getBean(ServerService.class).getLoginServerUrl()+"/kf_rank/fetch", Request.METHOD.POST).setParams(params);
        Response response = Sender.create(request).setTimeout(1000).send();

        if (response.getContent() != null) {
            RespCrossRankView respCrossRankView = Json.fromJson(RespCrossRankView.class, response.getContent());
            respCrossRankView.setLevelLimit(levelLimit);
            /**设置自己的排名*/
            respCrossRankView.calMeRank(role.getGid());
            MessagePusher.pushMessage(role, respCrossRankView);
            return ;
        }

        /**默认没有数据*/
        RespCrossRankView respCrossRankView = new RespCrossRankView();
        respCrossRankView.setType(rankType);
        respCrossRankView.setLevelLimit("");
        respCrossRankView.setList(new ArrayList<>());
        respCrossRankView.setCount((short) respCrossRankView.getList().size());
        respCrossRankView.setCookie(new Long(System.currentTimeMillis() / 1000).intValue());
        MessagePusher.pushMessage(role, respCrossRankView);
    }

    public String getKey(short rankType, String levelLimit) {
        if (!Strings.isEmpty(levelLimit)) {
            return rankType + ":" + levelLimit;
        }

        return String.valueOf(rankType);
    }

    /**添加装备宠物查看信息*/
    public void addRankView(String id, List<EquipField> list) {
        RankViewData rankViewData = RankDataPool.rankViewMap.computeIfAbsent(id, k-> new RankViewData(id, list));
        rankViewData.setFieldList(list);
        rankViewData.save();
    }

    /**移除装备宠物查看信息*/
    public void removeRandView(String id) {
        RankViewData rankViewData = RankDataPool.rankViewMap.remove(id);
        if (rankViewData != null) {
            rankViewData.setDelete(true);
            rankViewData.save();
            log.warn("====removeRandView id:{}", id);
        }
    }

    /**数据库加载装备宠物查看信息*/
    public void loadRankView() {
        Dao dao = SpringUtils.getBean(Dao.class);
        List<RankViewData> list = dao.query(RankViewData.class, Cnd.NEW());
        if (list != null) {
            Map<String, RankViewData> rankViewMap = new ConcurrentHashMap<>();
            for (RankViewData rankViewData : list) {
                rankViewMap.put(rankViewData.getId(), rankViewData);
            }

            RankDataPool.rankViewMap = rankViewMap;
        }
    }

    /**上传装备宠物查看信息到登录服*/
    public void uploadRankViewToLogin() {
        String serverName = SpringUtils.getBean(ServerService.class).getServer().getName();
        Set<String> keySet = RankDataPool.rankViewMap.keySet();
        RankViewData rankViewData = null;
        for (String key : keySet) {
            rankViewData = RankDataPool.rankViewMap.get(key);
            if (rankViewData == null) {continue;}

            Map<String, Object> params = new HashMap<>();
            params.put("data", Json.toJson(rankViewData, JsonFormat.compact()));
            params.put("serverName", serverName);
            try {
                Request request = Request.create(SpringUtils.getBean(ServerService.class).getLoginServerUrl()+"/kf_rank/upload_view", Request.METHOD.POST).setParams(params);
                Sender.create(request).setTimeout(1000).send();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**从登录服获得装备宠物查看信息*/
    public RankViewData fetchRankView(String id) {
        Map<String, Object> params = new HashMap<>();
        params.put("key", id);

        try {
            Request request = Request.create(SpringUtils.getBean(ServerService.class).getLoginServerUrl()+"/kf_rank/fetch_view", Request.METHOD.POST).setParams(params);
            Response response = Sender.create(request).setTimeout(1000).send();
            if (response.getContent() != null) {
                return Json.fromJson(RankViewData.class, response.getContent());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}
